Skip to content

Conversation

@HuaHuaY
Copy link
Contributor

@HuaHuaY HuaHuaY commented Oct 10, 2025

This is a draft PR now. I follow Java's implementation but I think it is not a good enough design for C++. Because we must copy lots of code from file_writer.cc or file_reader.cc and it will be troublesome to maintain in the future. I prefer to implement some classes inheriting XXXWriter or XXXReader. I'll think about how to refactor the code. If anyone has any good suggestions, please comment.

Now I have written two kinds of tests. Test the horizontal splicing and vertical splicing of parquet files separately. But only horizontal splicing is implemented now because I don't find an efficient way to merge two parquet files' schema.

Rationale for this change

Allow to rewrite parquet files in binary data formats instead of reading, decoding all values and writing them.

What changes are included in this PR?

  1. Add class ParquetFileRewriter and RewriterProperties.
  2. Add some to_thrift and SetXXX methods to help me copy the metadata.
  3. Add CopyStream methods to call memcpy between ArrowInputStream and ArrowOutputStream.
  4. Add RowGroupMetaDataBuilder::NextColumnChunk(std::unique_ptr<ColumnChunkMetaData> cc_metadata, int64_t shift) which allows to add column metadata without creating ColumnChunkMetaDataBuilder.

Are these changes tested?

Yes

Are there any user-facing changes?

  1. Add some new classes and methods mentioned above.
  2. ReaderProperties::GetStream is changed to a const method. Only the signature has been changed. Its original implementation allows it to be declared as a const method.

@github-actions
Copy link

Thanks for opening a pull request!

If this is not a minor PR. Could you open an issue for this pull request on GitHub? https://github.com/apache/arrow/issues/new/choose

Opening GitHub issues ahead of time contributes to the Openness of the Apache Arrow project.

Then could you also rename the pull request title in the following format?

GH-${GITHUB_ISSUE_ID}: [${COMPONENT}] ${SUMMARY}

or

MINOR: [${COMPONENT}] ${SUMMARY}

See also:

@HuaHuaY HuaHuaY changed the title [C++][Parquet] Implement basic parquet file rewriter [C++][Parquet] GH-47628: Implement basic parquet file rewriter Oct 10, 2025
@HuaHuaY
Copy link
Contributor Author

HuaHuaY commented Oct 13, 2025

@pitrou @adamreeve @mapleFU Do you have any suggestions about this draft? Is there any efficient way to merge two parquet files' schema?

Copy link
Member

@mapleFU mapleFU left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Emm I'm thinking that just reuse the current code a ok way, since these logic in current impl would be a bit hacking with current interface...

template <typename Builder>
void SerializeIndex(
const std::vector<std::vector<std::unique_ptr<Builder>>>& page_index_builders,
const std::vector<std::vector<std::unique_ptr<Index<Builder>>>>& page_indices,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this separate to different method? This reuse is a bit hacking to me

@github-actions github-actions bot added awaiting committer review Awaiting committer review and removed awaiting review Awaiting review labels Oct 13, 2025
Copy link
Member

@wgtmac wgtmac left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't reviewed all the changes yet and will progressively post my comments.

Copy link
Member

@wgtmac wgtmac left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The general workflow of the rewriter looks good to me. However, I don't believe we should directly manipulate the thrift objects.

RowGroupRewriter(std::shared_ptr<ArrowInputFile> source,
std::shared_ptr<ArrowOutputStream> sink,
const RewriterProperties* props,
std::shared_ptr<RowGroupReader> row_group_reader,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps introduce a RowGroupContext to hold all row group xxx readers?

auto column_index = page_index_reader_->GetColumnIndex(i);
auto offset_index = page_index_reader_->GetOffsetIndex(i);
// TODO(HuaHuaY): support bloom filter writer
[[maybe_unused]] auto bloom_filter =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is blocked by #37400

}

total_bytes_written += metadata_->total_byte_size();
} else {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we need to split this into smaller but dedicated functions?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants